﻿using System;
using System.Windows.Forms;
using WangfsLib.Interface.VlcPlayer;

namespace WPlayer
{
    public partial class Form1 : Form, IMediaController
    {
        VlcMediaPlayer player;
        long total;
        string file;

        public Form1()
        {
            InitializeComponent();

            this.contextMenuStrip2.Items.Add("置顶", null, this.onSetTop);
            this.contextMenuStrip2.Items.Add("加密", null, this.onToolClicked);

            this.player = new VlcMediaPlayer(System.IO.Path.Combine(Application.StartupPath, "plugin"));
            this.player.Started += Player_Started;
            this.player.Paused += Player_Paused;
            this.player.Stopped += Player_Stopped;
            this.player.TimeChanged += Player_TimeChanged;
            this.player.PasswordRequired += this.OnRequirePwd;
        }

        #region 播放器事件

        private void Player_TimeChanged(object sender, TimeChangedEventArgs e)
        {
            if (this.Disposing || this.IsDisposed) return;
            this.BeginInvoke((Action)(() =>
            {
                this.trackBar1.Value = Math.Min((int)e.TimeSpan.TotalMilliseconds, this.trackBar1.Maximum);
                this.lblTime.Text = e.TimeSpan.ToString(@"hh\:mm\:ss");
            }));
        }
        private void Player_Stopped(object sender, EventArgs e)
        {
            this.Invoke((Action)(() =>
            {
                this.trackBar1.Enabled = false;
                this.btnStop.Enabled = false;
                this.btnOpenPause.Image = Properties.Resources.play;
                this.Text = "WPlayer";
                this.lblTime.Text = this.lblTotal.Text = "00:00:00";
                if (this.WindowState == FormWindowState.Maximized) this.WindowState = FormWindowState.Normal;
            }));
        }
        private void Player_Started(object sender, EventArgs e)
        {
            this.total = this.player.GetTotalTime();
            this.Invoke((Action)(() =>
            {
                this.trackBar1.Enabled = true;
                this.btnStop.Enabled = true;
                this.btnOpenPause.Image = Properties.Resources.pause;
                this.Text = "WPlayer - " + this.file;
                this.trackBar1.Maximum = (int)this.total;
                this.lblTotal.Text = new TimeSpan(10000 * this.total).ToString(@"hh\:mm\:ss");
            }));
        }
        private void Player_Paused(object sender, EventArgs e) => this.Invoke((Action)(() => this.btnOpenPause.Image = Properties.Resources.play));

        void OnRequirePwd(Func<string, bool> func)
        {
            using (var dlg = new Form2(func)) dlg.ShowDialog(this);
        }

        public void SetCtrlBarVisible(bool visible)
        {
            if (this.panel1.Visible = visible)
            {
                this.panel2.Height = this.Height - this.panel1.Height - 39;
            }
            else
            {
                this.panel2.Height = this.Height;
            }
        }
        public void SetTimeBarVisible(bool visible) => this.panel1.Visible = visible;

        #endregion

        #region 重写

        protected override void OnShown(EventArgs e) => this.player.BindClient(this.panel2.Handle);
        protected override bool ProcessKeyPreview(ref Message m)
        {
            if (m.Msg == 0x100)
            {
                if (m.WParam.ToInt32() == 0x74) new Form3().Show();
            }
            return base.ProcessKeyPreview(ref m);
        }
        protected override void OnFormClosed(FormClosedEventArgs e) => this.player = null;

        #endregion

        #region 时间条

        private void trackBar1_Scroll(object sender, EventArgs e) => this.player.SeekTime((this.trackBar1.Value));

        private void trackBar1_MouseUp(object sender, MouseEventArgs e) => this.player.SeekTime((long)(e.X * 1.0 / this.trackBar1.Width * this.total));

        #endregion

        #region 拖拽文件

        private void Form1_DragEnter(object sender, DragEventArgs e)
        {
            var fs = e.Data.GetData("FileDrop") as string[];
            if (fs == null || fs.Length == 0 || Program.IsInvalidFile(fs[0])) return;
            e.Effect = DragDropEffects.Link;
        }

        private void Form1_DragDrop(object sender, DragEventArgs e)
        {
            var fs = e.Data.GetData("FileDrop") as string[];
            if (fs == null || fs.Length == 0) return;
            string file = fs[0];
            this.PlayFile(file);
        }

        #endregion

        void PlayFile(string file)
        {
            if (Program.IsInvalidFile(file)) return;
            if (!this.player.PlayFile(this.file = file)) return;
        }

        // 停止按钮
        private void btnStop_Click(object sender, EventArgs e) => this.player.Stop();
        // 播放按钮
        private void btnOpenPause_Click(object sender, EventArgs e)
        {
            switch (this.player.Status)
            {
                case PlayerStatus.Playing:
                    this.player.Pause();
                    break;
                case PlayerStatus.Paused:
                    this.player.Resume();
                    break;
                default:
                    using (var dlg = new OpenFileDialog() { Title = "打开媒体文件", Filter = "请选择多媒体文件|*.*", CheckFileExists = true })
                    {
                        if (dlg.ShowDialog() != DialogResult.OK) return;
                        this.PlayFile(dlg.FileName);
                    }
                    break;
            }
        }
        // 设置倍速
        private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            this.contextMenuStrip1.Hide();
            float r = float.Parse(e.ClickedItem.Text);
            this.player.SetRate(r);
            this.label1.Text = "倍速：" + e.ClickedItem.Text;
        }
        // 倍速菜单
        private void label1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left) return;
            this.contextMenuStrip1.Show(this.label1, e.Location);
        }

        // 音量
        private void trackBar2_Scroll(object sender, EventArgs e)
        {
            int vol = this.trackBar2.Value;
            new System.Threading.Thread(() => this.player.SetVolume(vol)).Start();
            this.toolTip1.SetToolTip(this.trackBar2, "音量：" + vol);
        }

        // 工具
        private void label2_Click(object sender, EventArgs e) => this.contextMenuStrip2.Show(this.label2, (e as MouseEventArgs).Location);

        void onSetTop(object sender, EventArgs e) => (sender as ToolStripMenuItem).Checked = this.TopMost = !this.TopMost;
        void onToolClicked(object sender, EventArgs e) => new Form3().Show();
    }
}
